package com.lujieni.springbootmybatis.aop;


import com.lujieni.springbootmybatis.context.TenantContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 忽略多租户的 Aspect，基于 {@link TenantIgnore} 注解实现，用于一些全局的逻辑。
 * 例如说，一个定时任务，读取所有数据，进行处理。
 * 又例如说，读取所有数据，进行缓存。
 *
 * @author 芋道源码
 */
@Aspect
@Slf4j
// 添加这个注解,让Spring管理这个Bean
@Component
public class TenantIgnoreAspect {

    @Around("@annotation(com.lujieni.springbootmybatis.aop.TenantIgnore)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 获取注解
        TenantIgnore tenantIgnore = AnnotationUtils.findAnnotation(method, TenantIgnore.class);
        if (tenantIgnore != null && tenantIgnore.enable()) {
            log.info("TenantIgnoreAspect 拦截到方法: {}, 忽略租户: {}",
                    joinPoint.getSignature().getName(), tenantIgnore.enable());
            try {
                TenantContextHolder.setIgnore(true);
                log.info("已设置忽略租户标志");
                // 执行逻辑
                return joinPoint.proceed();
            } finally {
                TenantContextHolder.clearIgnore();
                log.info("已清除忽略租户标志");
            }
        } else {
            return joinPoint.proceed();
        }
    }

}
